home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / smaltalk / manchest.lha / MANCHESTER / manchester / 4.1 / interactors / Interactors-PenPad.st < prev    next >
Text File  |  1993-07-24  |  11KB  |  396 lines

  1. TextInteractor subclass: #StructuredTextInteractor
  2.     instanceVariableNames: 'layoutDescription selectionEmphasis selectionBlock contextList '
  3.     classVariableNames: 'DefaultSelectionEmphasis '
  4.     poolDictionaries: ''
  5.     category: 'Interactors-PenPad'!
  6.  
  7.  
  8. !StructuredTextInteractor methodsFor: 'initialize-release'!
  9.  
  10. initialize
  11.     self selectionEmphasis: self defaultSelectionEmphasis.
  12.     super initialize! !
  13.  
  14. !StructuredTextInteractor methodsFor: 'accessing'!
  15.  
  16. addChild: aLayoutDescription
  17.     self layoutDescription: aLayoutDescription.
  18.     self component: self layoutDescription contents asComposedText!
  19.  
  20. contextList
  21.     ^contextList!
  22.  
  23. contextList: c
  24.     contextList := c!
  25.  
  26. layoutDescription
  27.     ^layoutDescription!
  28.  
  29. layoutDescription: ld
  30.     layoutDescription := ld!
  31.  
  32. selectionBlock
  33.     ^selectionBlock!
  34.  
  35. selectionBlock: aBlock
  36.     selectionBlock := aBlock!
  37.  
  38. selectionEmphasis
  39.     ^selectionEmphasis!
  40.  
  41. selectionEmphasis: emphasis
  42.     selectionEmphasis := emphasis! !
  43.  
  44. !StructuredTextInteractor methodsFor: 'event response'!
  45.  
  46. clearSelection
  47.  
  48.     (self component text)
  49.         emphasizeFrom: 1 to: self component text size with: #()!
  50.  
  51. selectDown
  52.     | cblock |
  53.     self clearSelection.
  54.     cblock := self component characterBlockAtPoint: self sensor cursorPoint - self origin.
  55.     (self
  56.         contextList: (self layoutDescription subjectAt: cblock stringIndex) reverse;
  57.         setSelection: self contextList removeFirst;
  58.         sensor) waitNoButton!
  59.  
  60. selectDownDown
  61.  
  62.     (self
  63.         clearSelection;
  64.         contextList) isEmpty
  65.             ifTrue: [self selectDown]
  66.             ifFalse: [self setSelection: self contextList removeFirst].
  67.     self sensor waitNoButton!
  68.  
  69. setSelection: aWordContext
  70.  
  71.     | start stop |
  72.     start := aWordContext startPosition.
  73.     stop := aWordContext endPosition.
  74.     (self component text at: stop) == $  ifTrue: [stop := stop - 1].
  75.     (self component text) emphasizeFrom: start to: stop with: self selectionEmphasis.
  76.     self render; damaged.
  77.     self selectionBlock notNil ifTrue: [self selectionBlock value: self value: aWordContext]! !
  78.  
  79. !StructuredTextInteractor methodsFor: 'private'!
  80.  
  81. defaultSelectionEmphasis
  82.     ^DefaultSelectionEmphasis!
  83.  
  84. justifiedOrigin
  85.     "Performing any kind of justification buggers the selection process"
  86.  
  87.     ^self origin! !
  88. "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
  89.  
  90. StructuredTextInteractor class
  91.     instanceVariableNames: ''!
  92.  
  93.  
  94. !StructuredTextInteractor class methodsFor: 'class initialization'!
  95.  
  96. initialize
  97.     "The DefaultSelectionEmphasis can be anything satisfying:
  98.         #([bold] [italic] [large normal small] [sansSerif serif] [strikeout] [underline] [subscript superscript])"
  99.  
  100.     DefaultSelectionEmphasis := #(bold)! !
  101.  
  102. LinearInteractor subclass: #OriginalScrollingInteractor
  103.     instanceVariableNames: 'offset visibleExtent localPixmap rendered localGraphicsContext hScroller vScroller '
  104.     classVariableNames: ''
  105.     poolDictionaries: ''
  106.     category: 'Interactors-PenPad'!
  107. OriginalScrollingInteractor comment:
  108. 'I wrap up an almost autonomous collection of interactors that can be scrolled arbitrarily, in any combination of horizontal and vertical directions. I cache the visual representation of my components so that they do not have to render themselves entirely onto my graphicsContext within some clipping rectangle every time they are scrolled.  There are obviously some updating issues to be addressed here, since updates into the localPixmap must also make it onto the enclosing pixmap.
  109.  
  110. component                (Interactor) the interactor which I scroll
  111.  
  112. offest                    (Point) the offset (due to scrolling) of my component
  113.  
  114. visibleExtent            (Point) the amout of the localPixmap (from the offset) that can be
  115.                         seen (excludes the scrollbars)
  116.  
  117. localPixmap            (Pixmap) the cached visual representation of my component
  118.  
  119. localGraphicsContext    (GraphicsContext) a cached graphicsContext on the localPixmap
  120.  
  121. [h|v]Scroller                ([Horizontal | Vertical]Scrollbar) either the relevant type of scrollbar,
  122.                         or nil for no scrollbar in that dimension
  123.  
  124. rendered                (Boolean) true if the component has already rendered itself on the localPixmap'!
  125.  
  126.  
  127. !OriginalScrollingInteractor methodsFor: 'initialize-release'!
  128.  
  129. initialize
  130.     super initialize.
  131.     self
  132.         rendered: false;
  133.         offset: 0@0!
  134.  
  135. useBothScrollers
  136.  
  137.     self useHorizontalScroller; useVerticalScroller!
  138.  
  139. useHorizontalScroller
  140.  
  141.     hScroller := HScroller new target: self!
  142.  
  143. useVerticalScroller
  144.  
  145.     vScroller := VScroller new target: self! !
  146.  
  147. !OriginalScrollingInteractor methodsFor: 'hierarchy'!
  148.  
  149. installSensor: aSensor
  150.  
  151.     self sensor: aSensor.
  152.     component installSensor: (ScrollerSensor new setWindow: window windowSensor: aSensor).
  153.     component sensor globalOrigin: self origin + (self scrollerCorrection x @ 0).
  154.     hScroller isNil ifFalse: [hScroller installSensor: aSensor].
  155.     vScroller isNil ifFalse: [vScroller installSensor: aSensor].! !
  156.  
  157. !OriginalScrollingInteractor methodsFor: 'accessing'!
  158.  
  159. hScroller
  160.     ^hScroller!
  161.  
  162. hScroller: s
  163.     hScroller := s!
  164.  
  165. localGraphicsContext
  166.     ^localGraphicsContext!
  167.  
  168. localGraphicsContext: gc
  169.     localGraphicsContext := gc!
  170.  
  171. localPixmap
  172.     ^localPixmap!
  173.  
  174. localPixmap: p
  175.     localPixmap := p!
  176.  
  177. offset
  178.     ^offset!
  179.  
  180. offset: o
  181.     offset := o!
  182.  
  183. rendered
  184.     ^rendered!
  185.  
  186. rendered: r
  187.     rendered := r!
  188.  
  189. visibleExtent
  190.     ^visibleExtent!
  191.  
  192. visibleExtent: ve
  193.     visibleExtent := ve!
  194.  
  195. vScroller
  196.     ^vScroller!
  197.  
  198. vScroller: s
  199.     vScroller := s! !
  200.  
  201. !OriginalScrollingInteractor methodsFor: 'geometry'!
  202.  
  203. computeBounds: bounds
  204.  
  205.     | ve ce sc |
  206.     self visibleExtent: (ve := bounds extent - (sc := self scrollerCorrection)).
  207.     ce := self component minimumExtent.
  208.     "(ve x < ce x or: [ve y < ce y]) ifTrue: [self uimsError]."
  209.     self bounds: bounds.
  210.     self component computeBounds: (0@0 extent:
  211.             (self component hRigid ifTrue: [ce x] ifFalse: [ce x max: ve x]) @
  212.             (self component vRigid ifTrue: [ce y] ifFalse: [ce y max: ve y])).
  213.     self
  214.         invalidateCachedCopy;
  215.         offset: 0@0;
  216.         setRanges;
  217.         setBars.
  218.  
  219.     vScroller notNil ifTrue: [vScroller bounds: (bounds origin corner: 1@-1 * sc + bounds bottomLeft + (0@1))]. "ASSUMES V-SCROLLERS ON THE LEFT!!!!!!"
  220.  
  221.     hScroller notNil ifTrue: [hScroller bounds: (1@-1 * sc + bounds bottomLeft - (1@0) corner: bounds corner)].
  222.     ^self bounds!
  223.  
  224. computeExtent
  225.  
  226.     | excess ext |
  227.     ext := self component computeExtent.
  228.     (self localPixmap isNil or: [(1@1 + ext <= self localPixmap extent) not])
  229.         ifTrue: [self newPixmapExtent: 1@1 + ext].
  230.     excess :=
  231.         (self hScroller notNil ifTrue: [self hScroller minExtent] ifFalse: [Point zero]) +
  232.         (self vScroller notNil ifTrue: [self vScroller minExtent] ifFalse: [Point zero]).
  233.     ^(excess max: (self extent isNil
  234.         ifTrue: [self preferredExtent: ext + self scrollerCorrection]
  235.         ifFalse: [self extent])) max: 50@50! !
  236.  
  237. !OriginalScrollingInteractor methodsFor: 'rendering'!
  238.  
  239. damaged
  240.     self renderComponentOn: self parent graphicsContext.
  241.     super damaged!
  242.  
  243. graphicsContext
  244.     ^self localGraphicsContext!
  245.  
  246. graphicsContextFor: aComponent
  247.     ^self localGraphicsContext!
  248.  
  249. reallyRenderComponentOn: gc
  250.  
  251.     gc
  252.         clippingRectangle: ((self scrollerCorrection x @ 0 + self origin) extent: self visibleExtent);
  253.         translateBy: self origin.
  254.     self localPixmap
  255.         displayOn: gc
  256.         at: self offset negated + (self scrollerCorrection x @ 0).    "ASSUME H-SCROLLERS AT BOTTOM!!!!!!"
  257.     gc
  258.         translateBy: self origin negated;
  259.         clippingRectangle: nil!
  260.  
  261. reallyRenderOn: gc
  262.  
  263.     self reallyRenderComponentOn: gc.
  264.  
  265.     vScroller notNil ifTrue: [vScroller renderOn: gc].
  266.     hScroller notNil ifTrue: [hScroller renderOn: gc].
  267.  
  268.     self renderInactiveRegionOn: gc!
  269.  
  270. renderComponentOn: gc
  271.  
  272.     self rendered ifFalse: [self rendered: true; renderToCache].
  273.     self reallyRenderComponentOn: gc!
  274.  
  275. renderInactiveRegionOn: gc
  276.  
  277.     (vScroller notNil and: [hScroller notNil])
  278.         ifTrue: [gc
  279.                 paint: self selectionBackgroundColor;
  280.                 displayRectangle: (vScroller bounds bottomLeft corner: hScroller bounds bottomLeft)]!
  281.  
  282. renderOn: gc
  283.  
  284.     self rendered ifFalse: [self renderToCache; rendered: true].
  285.     self reallyRenderOn: gc!
  286.  
  287. renderToCache
  288.  
  289.     self component renderOn: self localGraphicsContext! !
  290.  
  291. !OriginalScrollingInteractor methodsFor: 'private'!
  292.  
  293. clearLocalPixmap
  294.  
  295.     self localGraphicsContext medium
  296.         background: self backgroundColor;
  297.         clear!
  298.  
  299. invalidateCachedCopy
  300.  
  301.     | ext pext |
  302.     ext := self visibleExtent max: self component extent.
  303.     pext := self localPixmap extent.
  304.     (ext x > pext x or: [ext y > pext y])
  305.         ifTrue: [self newPixmapExtent: ext]
  306.         ifFalse: [self clearLocalPixmap].
  307.     self rendered: false!
  308.  
  309. newPixmapExtent: newExtent
  310.  
  311.     (self
  312.         localPixmap: (Pixmap extent: newExtent);
  313.         localGraphicsContext: (GraphicsContext on: self localPixmap);
  314.         localGraphicsContext) font: FontDescription default.
  315.     self clearLocalPixmap!
  316.  
  317. scrollerCorrection
  318.  
  319.     ^((self vScroller notNil ifTrue: [vScroller width] ifFalse: [0])
  320.     @(self hScroller notNil ifTrue: [hScroller height] ifFalse: [0]))!
  321.  
  322. setBars
  323.     "set the size and position of the two scrollbars"
  324.  
  325.     vScroller isNil ifFalse: [vScroller
  326.         min: offset y;
  327.         max: offset y + self visibleExtent y].
  328.     hScroller isNil ifFalse: [hScroller
  329.         min: offset x;
  330.         max: offset x + self visibleExtent x].!
  331.  
  332. setRanges
  333.     "set the ranges of the two scrollbars"
  334.  
  335.     vScroller isNil ifFalse: [vScroller range: self component extent y].
  336.     hScroller isNil ifFalse: [hScroller range: self component extent x]! !
  337.  
  338. !OriginalScrollingInteractor methodsFor: 'scrolling'!
  339.  
  340. scrollBy: aPoint
  341.  
  342.     | newOffset corner componentExtent oldOffset |
  343.     aPoint isZero
  344.         ifFalse:
  345.             [oldOffset := self offset.
  346.             newOffset := aPoint * self warpFactor + self offset.
  347.             corner := newOffset + self visibleExtent.
  348.             componentExtent := self component extent.
  349.             corner x > componentExtent x ifTrue: [corner x: componentExtent x].
  350.             corner y > componentExtent y ifTrue: [corner y: componentExtent y].
  351.             corner x < self visibleExtent x ifTrue: [corner x: self visibleExtent x].
  352.             corner y < self visibleExtent y ifTrue: [corner y: self visibleExtent y].
  353.             self offset: corner - self visibleExtent.
  354.             self component sensor translateOrigin: oldOffset - self offset.
  355.             self
  356.                 renderOn: self parent graphicsContext;
  357.                 setBars;
  358.                 damaged]!
  359.  
  360. scrollDown
  361.     self scrollBy: 0@1!
  362.  
  363. scrollLeft
  364.     self scrollBy: -1@0!
  365.  
  366. scrollRight
  367.     self scrollBy: 1@0!
  368.  
  369. scrollUp
  370.     self scrollBy: 0@-1!
  371.  
  372. warpFactor
  373.     ^1! !
  374.  
  375. !OriginalScrollingInteractor methodsFor: 'event enquiry'!
  376.  
  377. interactorAt: aPoint
  378.  
  379.     | correction visibleOrigin |
  380.     hScroller isNil ifFalse:
  381.         [(hScroller containsPoint: aPoint) ifTrue:
  382.             [^hScroller interactorAt: aPoint]].
  383.     vScroller isNil ifFalse:
  384.         [(vScroller containsPoint: aPoint) ifTrue:
  385.             [^vScroller interactorAt: aPoint]].
  386.  
  387.     "*** I AM ABOUT TO ASSUME THAT SCROLLBARS ARE AT LEFT AND AT BOTTOM ***"
  388.  
  389.     correction := self scrollerCorrection.
  390.     visibleOrigin := self origin + (correction x @ 0).
  391.     ((visibleOrigin extent: self visibleExtent) containsPoint: aPoint)
  392.         ifTrue: [^self component interactorAt: aPoint - visibleOrigin + self offset].
  393.     ^nil! !
  394. StructuredTextInteractor initialize!
  395.  
  396.